import 'package:get/get.dart';
import 'package:flutter/material.dart';
import 'package:dio/dio.dart';
import '../utils/http/http_client.dart';
import '../models/api_response.dart';
import 'token_service.dart';

/// 国标视频服务类
/// 负责与WVP-GB28181-Pro平台交互，处理国标视频相关操作
class GBVideoService extends GetxService {
  // WVP平台基础URL
  final String baseUrl = 'http://47.120.9.38:18080';
  
  // 登录状态
  final RxBool isLoggedIn = false.obs;
  
  // 存储WVP平台的token
  String? _wvpToken;
  
  // 获取存储的WVP平台token
  String? get wvpToken => _wvpToken;
  
  // Dio实例
  late Dio _dio;
  
  /// 初始化服务
  Future<GBVideoService> init() async {
    try {
      debugPrint('初始化国标视频服务');
      
      // 初始化Dio
      _dio = Dio(BaseOptions(
        baseUrl: baseUrl,
        connectTimeout: const Duration(milliseconds: 15000),
        receiveTimeout: const Duration(milliseconds: 15000),
      ));
      
      // 尝试从本地存储获取token
      _wvpToken = TokenService.getGBVideoToken();
      
      // 如果有token，则认为已登录
      if (_wvpToken != null && _wvpToken!.isNotEmpty) {
        isLoggedIn.value = true;
        debugPrint('国标视频服务已从本地存储获取token');
      }
    } catch (e) {
      debugPrint('国标视频服务初始化时发生错误: $e');
      // 创建一个基本的Dio实例，避免后续操作出现空引用
      _dio = Dio(BaseOptions(
        baseUrl: baseUrl,
        connectTimeout: const Duration(milliseconds: 15000),
        receiveTimeout: const Duration(milliseconds: 15000),
      ));
    }
    
    return this;
  }
  
  /// 登录WVP平台
  /// @param username 用户名
  /// @param password 密码（MD5加密后的）
  Future<bool> login(String username, String password) async {
    try {
      debugPrint('===== 开始登录WVP视频平台 =====');
      debugPrint('正在向WVP平台发送登录请求...');
      
      // 先清除旧的token，确保使用新的token
      _wvpToken = null;
      isLoggedIn.value = false;
      
      final response = await _dio.get(
        '/api/user/login',
        queryParameters: {
          'username': username,
          'password': password
        }
      );
      
      debugPrint('收到WVP登录响应状态码: ${response.statusCode}');
      
      if (response.data['code'] == 0 && response.data['data'] != null) {
        final accessToken = response.data['data']['accessToken'];
        if (accessToken != null) {
          _wvpToken = accessToken;
          TokenService.saveGBVideoToken(accessToken);
          isLoggedIn.value = true;
          
          debugPrint('WVP-GB28181-Pro登录成功');
          debugPrint('AccessToken前15位: ${accessToken.toString().substring(0, 15)}...');
          debugPrint('===== WVP平台登录完成 =====');
          
          return true;
        }
      }
      
      debugPrint('WVP-GB28181-Pro登录失败: ${response.data['msg'] ?? "未知错误"}');
      return false;
    } catch (e) {
      debugPrint('WVP-GB28181-Pro登录出错: $e');
      // 确保失败时状态一致
      _wvpToken = null;
      isLoggedIn.value = false;
      TokenService.clearGBVideoToken();
      return false;
    }
  }
  
  /// 开始播放视频 - WVP平台接口
  /// @param deviceId 设备国标ID
  /// @param channelId 通道国标ID
  /// @param transport 传输协议，默认为TCP-ACTIVE
  Future<Map<String, dynamic>?> startPlay(String deviceId, String channelId, {String transport = 'TCP-ACTIVE'}) async {
    debugPrint('========== WVP视频点播请求开始 ==========');
    debugPrint('设备ID: $deviceId');
    debugPrint('通道ID: $channelId');
    debugPrint('传输协议: $transport');
    debugPrint('请求URL: /api/play/start/$deviceId/$channelId');
    
    // 检查登录状态并强制重新登录
    if (!isLoggedIn.value || _wvpToken == null || _wvpToken!.isEmpty) {
      debugPrint('WVP平台未登录或token为空，尝试重新登录');
      bool loginSuccess = await login('admin', '21232f297a57a5a743894a0e4a801fc3');
      if (!loginSuccess) {
        debugPrint('WVP平台登录失败，无法发起播放请求');
        return null;
      }
      debugPrint('WVP平台重新登录成功，继续处理播放请求');
    } else {
      debugPrint('WVP平台已登录状态，token前15位: ${_wvpToken!.length > 15 ? _wvpToken!.substring(0, 15) : _wvpToken}...');
    }
    
    try {
      // 打印完整请求信息便于调试
      debugPrint('发送请求到WVP平台');
      
      final response = await _dio.get(
        '/api/play/start/$deviceId/$channelId',
        queryParameters: {'transport': transport},
        options: Options(
          headers: {'access-token': _wvpToken},
        )
      );
      
      debugPrint('WVP视频点播响应状态码: ${response.statusCode}');
      
      if (response.data['code'] == 0 && response.data['data'] != null) {
        debugPrint('WVP视频点播响应成功');
        return response.data['data'];
      }
      
      debugPrint('WVP视频点播请求失败: ${response.data['msg']}');
      return null;
    } catch (e) {
      debugPrint('WVP视频点播请求出错: $e');
      // 如果是401错误，尝试重新登录后再试一次
      if (e is DioException && e.response?.statusCode == 401) {
        debugPrint('收到401错误，尝试重新登录后再次请求');
        logout(); // 清除可能已失效的token
        bool loginSuccess = await login('admin', '21232f297a57a5a743894a0e4a801fc3');
        if (loginSuccess) {
          debugPrint('重新登录成功，重试播放请求');
          try {
            final retryResponse = await _dio.get(
              '/api/play/start/$deviceId/$channelId',
              queryParameters: {'transport': transport},
              options: Options(
                headers: {'access-token': _wvpToken},
              )
            );
            
            if (retryResponse.data['code'] == 0 && retryResponse.data['data'] != null) {
              debugPrint('重试WVP视频点播响应成功');
              return retryResponse.data['data'];
            }
          } catch (retryError) {
            debugPrint('重试WVP视频点播请求仍然出错: $retryError');
          }
        }
      }
      return null;
    }
  }
  
  /// 停止播放视频 - WVP平台接口
  /// @param deviceId 设备国标ID
  /// @param channelId 通道国标ID
  Future<bool> stopPlay(String deviceId, String channelId) async {
    // 检查登录状态并强制重新登录
    if (!isLoggedIn.value || _wvpToken == null || _wvpToken!.isEmpty) {
      debugPrint('WVP平台未登录或token为空，尝试重新登录');
      bool loginSuccess = await login('admin', '21232f297a57a5a743894a0e4a801fc3');
      if (!loginSuccess) {
        debugPrint('WVP平台登录失败，无法停止播放视频');
        return false;
      }
    }
    
    try {
      debugPrint('停止播放视频，设备ID: $deviceId, 通道ID: $channelId');
      final response = await _dio.get(
        '/api/play/stop/$deviceId/$channelId',
        options: Options(
          headers: {'access-token': _wvpToken},
        )
      );
      
      return response.data['code'] == 0;
    } catch (e) {
      debugPrint('停止播放视频出错: $e');
      
      // 如果是401错误，尝试重新登录后再试一次
      if (e is DioException && e.response?.statusCode == 401) {
        debugPrint('收到401错误，尝试重新登录后再次请求');
        logout();
        bool loginSuccess = await login('admin', '21232f297a57a5a743894a0e4a801fc3');
        if (loginSuccess) {
          try {
            final retryResponse = await _dio.get(
              '/api/play/stop/$deviceId/$channelId',
              options: Options(
                headers: {'access-token': _wvpToken},
              )
            );
            return retryResponse.data['code'] == 0;
          } catch (retryError) {
            debugPrint('重试停止播放视频仍然出错: $retryError');
          }
        }
      }
      return false;
    }
  }
  
  /// 查询正在播放的视频
  Future<List<dynamic>> listPlayingVideos() async {
    // 检查登录状态并强制重新登录
    if (!isLoggedIn.value || _wvpToken == null || _wvpToken!.isEmpty) {
      debugPrint('WVP平台未登录或token为空，尝试重新登录');
      bool loginSuccess = await login('admin', '21232f297a57a5a743894a0e4a801fc3');
      if (!loginSuccess) {
        debugPrint('WVP平台登录失败，无法查询正在播放的视频');
        return [];
      }
    }
    
    try {
      debugPrint('查询正在播放的视频列表');
      final response = await _dio.get(
        '/api/play/list',
        options: Options(
          headers: {'access-token': _wvpToken},
        )
      );
      
      if (response.data['code'] == 0 && response.data['data'] != null) {
        return response.data['data'];
      }
      
      return [];
    } catch (e) {
      debugPrint('查询正在播放的视频出错: $e');
      
      // 如果是401错误，尝试重新登录后再试一次
      if (e is DioException && e.response?.statusCode == 401) {
        debugPrint('收到401错误，尝试重新登录后再次请求');
        logout();
        bool loginSuccess = await login('admin', '21232f297a57a5a743894a0e4a801fc3');
        if (loginSuccess) {
          try {
            final retryResponse = await _dio.get(
              '/api/play/list',
              options: Options(
                headers: {'access-token': _wvpToken},
              )
            );
            if (retryResponse.data['code'] == 0 && retryResponse.data['data'] != null) {
              return retryResponse.data['data'];
            }
          } catch (retryError) {
            debugPrint('重试查询正在播放的视频仍然出错: $retryError');
          }
        }
      }
      return [];
    }
  }
  
  /// 视频流保活
  /// @param stream 流ID
  Future<bool> keepaliveStream(String stream) async {
    // 检查登录状态并强制重新登录
    if (!isLoggedIn.value || _wvpToken == null || _wvpToken!.isEmpty) {
      debugPrint('WVP平台未登录或token为空，尝试重新登录');
      bool loginSuccess = await login('admin', '21232f297a57a5a743894a0e4a801fc3');
      if (!loginSuccess) {
        debugPrint('WVP平台登录失败，无法保活视频流');
        return false;
      }
    }
    
    try {
      debugPrint('视频流保活请求，流ID: $stream');
      final response = await _dio.get(
        '/api/play/keepalive',
        queryParameters: {'stream': stream},
        options: Options(
          headers: {'access-token': _wvpToken},
        )
      );
      
      return response.data['code'] == 0;
    } catch (e) {
      debugPrint('视频流保活出错: $e');
      
      // 如果是401错误，尝试重新登录后再试一次
      if (e is DioException && e.response?.statusCode == 401) {
        debugPrint('收到401错误，尝试重新登录后再次请求');
        logout();
        bool loginSuccess = await login('admin', '21232f297a57a5a743894a0e4a801fc3');
        if (loginSuccess) {
          try {
            final retryResponse = await _dio.get(
              '/api/play/keepalive',
              queryParameters: {'stream': stream},
              options: Options(
                headers: {'access-token': _wvpToken},
              )
            );
            return retryResponse.data['code'] == 0;
          } catch (retryError) {
            debugPrint('重试视频流保活仍然出错: $retryError');
          }
        }
      }
      return false;
    }
  }
  
  /// 云台控制 - WVP平台接口
  /// @param deviceId 设备国标ID
  /// @param channelId 通道国标ID
  /// @param command 控制命令
  /// @param horizonSpeed 水平速度(1-255)
  /// @param verticalSpeed 垂直速度(1-255)
  /// @param zoomSpeed 缩放速度(0-15)，注意这个范围是0-15而不是0-255
  Future<bool> ptzControl(String deviceId, String channelId, String command, {
    int horizonSpeed = 50,
    int verticalSpeed = 50,
    int zoomSpeed = 5,
  }) async {
    // 确保参数在有效范围内
    horizonSpeed = horizonSpeed.clamp(1, 255);
    verticalSpeed = verticalSpeed.clamp(1, 255);
    zoomSpeed = zoomSpeed.clamp(0, 15); // 确保zoomSpeed在0-15范围内
    
    // 检查登录状态并强制重新登录
    if (!isLoggedIn.value || _wvpToken == null || _wvpToken!.isEmpty) {
      debugPrint('WVP平台未登录或token为空，尝试重新登录');
      bool loginSuccess = await login('admin', '21232f297a57a5a743894a0e4a801fc3');
      if (!loginSuccess) {
        debugPrint('WVP平台登录失败，无法控制云台');
        return false;
      }
    }
    
    // 确保命令格式正确 - 与wvpRequest.js保持一致
    // 命令可能是: left/right/up/down/upleft/upright/downleft/downright/zoomin/zoomout/stop
    String normalizedCommand = command.toLowerCase();
    
    try {
      debugPrint('云台控制，设备ID: $deviceId, 通道ID: $channelId, 命令: $normalizedCommand, 速度参数: h=$horizonSpeed, v=$verticalSpeed, z=$zoomSpeed');
      final response = await _dio.get(
        '/api/front-end/ptz/$deviceId/$channelId',
        queryParameters: {
          'command': normalizedCommand,
          'horizonSpeed': horizonSpeed,
          'verticalSpeed': verticalSpeed,
          'zoomSpeed': zoomSpeed,
        },
        options: Options(
          headers: {'access-token': _wvpToken},
        )
      );
      
      if (response.statusCode == 200 && response.data['code'] == 0) {
        debugPrint('云台控制命令发送成功: $normalizedCommand');
        return true;
      } else {
        debugPrint('云台控制命令发送失败: ${response.data['msg'] ?? "未知错误"}');
        return false;
      }
    } catch (e) {
      debugPrint('控制云台出错: $e');
      
      // 如果是401错误，尝试重新登录后再试一次
      if (e is DioException && e.response?.statusCode == 401) {
        debugPrint('收到401错误，尝试重新登录后再次请求');
        logout();
        bool loginSuccess = await login('admin', '21232f297a57a5a743894a0e4a801fc3');
        if (loginSuccess) {
          try {
            final retryResponse = await _dio.get(
              '/api/front-end/ptz/$deviceId/$channelId',
              queryParameters: {
                'command': normalizedCommand,
                'horizonSpeed': horizonSpeed,
                'verticalSpeed': verticalSpeed,
                'zoomSpeed': zoomSpeed,
              },
              options: Options(
                headers: {'access-token': _wvpToken},
              )
            );
            
            if (retryResponse.statusCode == 200 && retryResponse.data['code'] == 0) {
              debugPrint('重试后云台控制命令发送成功: $normalizedCommand');
              return true;
            } else {
              debugPrint('重试后云台控制命令发送失败: ${retryResponse.data['msg'] ?? "未知错误"}');
              return false;
            }
          } catch (retryError) {
            debugPrint('重试控制云台仍然出错: $retryError');
          }
        }
      }
      return false;
    }
  }
  
  /// 登出WVP平台
  void logout() {
    _wvpToken = null;
    TokenService.clearGBVideoToken();
    isLoggedIn.value = false;
    debugPrint('已登出WVP平台');
  }
} 